import Web3 from "web3"
import config from "@/config/config.js"

import usdt_abi from "@/common/abi/usdt.js"
import btc_abi from "@/common/abi/btc.js"
import eth_abi from "@/common/abi/eth.js"

import Vue from "vue"
import store from '@/store/index'
import VueI18n from 'vue-i18n'

let i18n = null;
setTimeout(() => {
	i18n = new VueI18n({
		locale: store.state.lang ? store.state.lang.toString() : 'zh', // 语言标识
		messages: {
			'zh': require('@/common/lang/zh'), // 中文简体语言包
			'en': require('@/common/lang/en'), // 英语
		},
		silentTranslationWarn: true,
	})
}, 1000)






export async function connectWallet() {
	return new Promise(async (resolve, reject) => {
		if (window.ethereum) {
			let web3 = new Web3(window.ethereum);
			let accounts = await web3.eth.requestAccounts();
			Vue.prototype.defaultAddress = accounts[0];
			let netId = null;
			try {
				netId = window.ethereum.networkVersion; //同步检测
			} catch (e) {
				Vue.prototype.defaultAddress = ""
			}

			if (netId == 56 || netId == 97) { //bnb
				Vue.prototype.usdt_contract = new web3.eth.Contract(usdt_abi, config.usdt_address);
				Vue.prototype.btc_contract = new web3.eth.Contract(usdt_abi, config.btc_address);
				Vue.prototype.eth_contract = new web3.eth.Contract(usdt_abi, config.eth_address);
				Vue.prototype.netId = netId;
				resolve(Vue.prototype.defaultAddress);
			} else {
				Vue.prototype.defaultAddress = ""
				reject()
			}
		} else {
			reject()
		}
	})
}

//获取当前钱包地址
export async function getAddress() {
	return new Promise(async (resolve, reject) => {
		if (window.ethereum) {
			let web3 = new Web3(window.ethereum);
			let accounts = await web3.eth.requestAccounts();
			if (accounts[0]) {
				resolve(accounts[0])
			} else {
				resolve("")
			}
		} else {
			resolve("")
		}
	})
}

// 获取BNB余额
export async function getBalance() {
	if (!Vue.prototype.defaultAddress) {
		await connectWallet();
	}
	let balance = 0;

	const web3 = new Web3(window.ethereum);
	balance = await web3.eth.getBalance(Vue.prototype.defaultAddress);

	return balance ? balance : 0;
}

// 获取合约余额
export async function getContractBalance(token) {
	return new Promise(async (resolve, reject) => {
		if (!Vue.prototype.defaultAddress) {
			try {
				await connectWallet();
			} catch (e) {
				//TODO handle the exception
				return resolve(0);
			}
		}
		let web3 = new Web3(window.ethereum);
		let contract = new web3.eth.Contract(usdt_abi, token);
		/*if (currency === 'usdt') contract = Vue.prototype.usdt_contract
		if (currency === 'btc') contract = Vue.prototype.btc_contract
		if (currency === 'eth') contract = Vue.prototype.eth_contract*/
		
		if (!contract) {

			return resolve(0);
		}

		let decimals = 18;
		let balance = 0

		try {

			balance = await contract.methods.balanceOf(Vue.prototype.defaultAddress).call();


		} catch (e) {
			//TODO handle the exception
			console.log("获取余额失败");
			return resolve(0);

		}
		try {
			decimals = await contract.methods.decimals().call();
		} catch (e) {
			//TODO handle the exception
			//reject("获取余额失败")
			return resolve(0);
		}
		let _decimals = 10 ** decimals
		Vue.prototype.decimals = decimals;
		Vue.prototype.contract = contract;
		resolve((balance / _decimals).toFixed(4))
	})

}

// 合约交易
export async function contractTransfer(receiveAddress, num,token) {
	
	return new Promise(async (resolve, reject) => {
		try {
			const defaultAddress = Vue.prototype.defaultAddress; //当前地址

			let balance = await getBalance(); //获取bnb余额
			
			let gasAmount = 100000; //await contract.methods.transfer(receiveAddress, sendNum).estimateGas({ from: defaultAddress });
			gasAmount = parseInt(gasAmount * 1.2);
			let _web3 = new Web3(window.ethereum);
			let gasPrice = "5000000000"; // await _web3.eth.getGasPrice();

			let transferFee = gasAmount * gasPrice;
			if (balance < transferFee) return reject({ msg: i18n.t('手续费不足') }); //手续费不足
			// 计算手续费-end

			let contractBalance = await getContractBalance(token); //获取合约币种余额

			if (contractBalance * 1 < num * 1) return reject({ msg: i18n.t('余额不足') }); //余额不足

			let decimals = Vue.prototype.decimals;
			let sendNum = BigInt(num * Math.pow(10, decimals)).toString();
			let contract = Vue.prototype.contract;
			if (!contract) return reject({ msg: "交易失败" }); //交易失败

			contract.methods.transfer(receiveAddress, sendNum).send({ from: defaultAddress, gasPrice: gasPrice }, (err, txid) => {
				if (err == null) return resolve(txid);
				return reject({ msg: err.message }); //交易失败
			});
		} catch (error) {
			console.log("交易失败", error);
			const regex = /"message":\s*"([^"]*)"/;
			const match = error.message.match(regex);
			const message = match ? match[1] : null;
			return reject({ msg: message ? message : "交易失败" }); //交易失败
		}
	})
}

// 获取签名
export async function signMessage(message) {
	return new Promise(async (resolve, reject) => {
		if (!Vue.prototype.defaultAddress) {
			await connectWallet();
		}
		if (Vue.prototype.netId == -1) {
			var hexStr = window.tronWeb.toHex(message);
			try {
				return await window.tronWeb.trx.sign(hexStr);
			} catch (e) {
				//TODO handle the exception
				return false
			}
		} else {
			let _web3 = new Web3(window.ethereum);
			let hexStr = _web3.utils.utf8ToHex(message);

			try {
				const s = await _web3.eth.personal.sign(hexStr, Vue.prototype.defaultAddress);
				resolve(s)
			} catch (e) {
				//TODO handle the exception
				reject()
			}
		}
	})
}


// 查询交易状态
export async function checkTransaction(txid, callback) {

	if (!Vue.prototype.defaultAddress) await connectWallet();

	let _web3 = new Web3(window.ethereum);
	let maxnum = 0;
	let interval = setInterval(() => {
		_web3.eth.getTransactionReceipt(txid, (err, ret) => {
			if (err == null && ret) {
				clearInterval(interval);
				if (ret["status"] == true) {
					uni.hideLoading();
					callback(true);
				}
			} else {
				maxnum++;
				if (maxnum >= 10) {
					clearInterval(interval);
					uni.hideLoading();
					callback(false);
				}
			}
		}).catch((ret) => {
			clearInterval(interval);
			uni.hideLoading();
			callback(true);
		})
	}, 3000);
}